package com.example.shiwu.util;

import com.google.firebase.crashlytics.buildtools.reloc.com.google.common.primitives.Ints;
import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;

import java.util.Arrays;

public class BitUtils {
    public static void main(String[] args) {
        System.out.println(Arrays.toString(hexStrToBits("0013")));
        System.out.println(bitStrToHex("10000010011"));
    }
    public static byte bitStrToByte(String bitStr) {
        int re, len;
        if (bitStr == null) {
            return 0;
        }
        len = bitStr.length();
        if (len != 4 && len != 8) {
            return 0;
        }
        if (len == 8) {//8 bit 处理
            if (bitStr.charAt(0) == '0') {
                re = Integer.parseInt(bitStr, 2);
            } else {//负数
                re = Integer.parseInt(bitStr, 2) - 256;
            }
        } else { //4 bit 处理
            re = Integer.parseInt(bitStr, 2);
        }

        return (byte) re;
    }

    public static String byteToBitStr(byte by) {
        return ""
                + (byte) ((by >> 7) & 0x1) + (byte) ((by >> 6) & 0x1)
                + (byte) ((by >> 5) & 0x1) + (byte) ((by >> 4) & 0x1)
                + (byte) ((by >> 3) & 0x1) + (byte) ((by >> 2) & 0x1)
                + (byte) ((by >> 1) & 0x1) + (byte) ((by) & 0x1);
    }
    public static byte[] byteToBitByByteArr(byte by) {
        byte[] bits = new byte[8];
        for (int i = 7; i >= 0; i--) {
            bits[i] = (byte) (by & 1);
            by = (byte) (by >> 1);
        }

        return bits;
    }

    public static byte[] bitsToBytes(String bits) {
        char[] chars = bits.toCharArray();
        byte[] bytes = new byte[chars.length];
        for (int i = 0; i < chars.length; i++) {
            bytes[i] = Byte.parseByte(String.valueOf(chars[i]));
        }
        return bitsToBytes(Arrays.toString(bytes));
    }


    /**
     * byte to bit array by Boolean array
     *
     * @param by
     * @return
     */
    public static boolean[] byteToBitByBooleanArr(byte by) {
        boolean[] bits = new boolean[8];
        for (int i = 7; i >= 0; i--) {
            bits[i] = (by & 1) == 1;
            by = (byte) (by >> 1);
        }
        return bits;
    }

    /**
     * 字节数组转换成以字节表示为比特的数组
     *
     * @param bytes
     * @return
     */
    public static byte[] bytesToBits(byte[] bytes) {
        byte[] temp = new byte[bytes.length * 8];
        for (int i = 0; i < bytes.length; i++) {
            byte[] bits = byteToBitByByteArr(bytes[i]);
            System.arraycopy(bits, 0, temp, i * 8, 8);
        }
        return temp;
    }

    public static byte[] hexStrToBits(String hex) {
        if (hex.contains("H")) {
            hex = hex.replace("H", "");
        }
        return bytesToBits(ByteUtils.hexToBytes(hex));
    }

    public static String hexStrToBits(String hex, int len) {
        if (hex.contains("H")) {
            hex = hex.replace("H", "");
        }
        byte[] bits = bytesToBits(ByteUtils.hexToBytes(hex));
        int hexLen = hex.length() * 4;
        StringBuilder sb = new StringBuilder();
        if (hexLen >= len) { //取后len位
            for (int i = bits.length - len; i < bits.length; i++) {
                sb.append(bits[i]);
            }
        } else {//前面填充0
            for (int i = 0; i < len - hexLen; i++) {
                sb.append("0");
            }
            for (byte bit : bits) {
                sb.append(bit);
            }
        }
        return sb.toString();
    }


    public static String bitStrToHex(String param) {
        //前面需要填充0的个数
        int remain = param.length() % 8;
        int num = 0;
        if (remain > 0) {
            num = 8 - remain;
        }
        String bits = param;
        if (num > 0) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < num; i++) {
                sb.append(0);
            }
            sb.append(param);
            bits = sb.toString();
        }
        return HexBin.encode(bitsToBytes(bits));
    }

    /**
     * 截取后len位bit
     *
     * @param value
     * @param len
     * @return
     */
    public static String intToBits(int value, int len) {
        StringBuilder sb = new StringBuilder();
        byte[] bits = bytesToBits(Ints.toByteArray(value));
        for (int i = bits.length - len; i < bits.length; i++) {
            sb.append(bits[i]);
        }
        return sb.toString();
    }
}
